package energy;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;

import org.apache.log4j.Logger;

public class Calibrator extends AbstractDataProcessor {

	private static Logger log = Logger.getLogger("energy.Calibrator");
	private static final String CALIBRATION_PROPERTIES = "resources/calibration.properties";
	private static Properties properties;
	
	static {
		properties = new Properties();
		try {
			properties.load(new FileReader(CALIBRATION_PROPERTIES));
		} catch (FileNotFoundException e) {
			log.error("Calibration properties file did not exist.", e);
		} catch (IOException e) {
			log.error("Could not load calibration properties.", e);
		}
	}
	
	Condensator condensator;

	private double even[] = new double[3];
	private double odd[] = new double[3];
	
	private EnergyData previous;
	
	public Calibrator(Condensator condensator) {
		this.condensator = condensator;
		loadValues();
	}
	
	private void loadValues() {
		try {
			even[0] = Double.parseDouble(String.valueOf(properties.get(condensator.name() + ".even.a")));
			even[1] = Double.parseDouble(String.valueOf(properties.get(condensator.name() + ".even.b")));
			//even[2] = Double.parseDouble(String.valueOf(properties.get(condensator.name() + ".even.c")));
			odd[0] = Double.parseDouble(String.valueOf(properties.get(condensator.name() + ".odd.a")));
			odd[1] = Double.parseDouble(String.valueOf(properties.get(condensator.name() + ".odd.b")));
			//odd[2] = Double.parseDouble(String.valueOf(properties.get(condensator.name() + ".odd.c")));
		} catch(NumberFormatException e) {
			log.error("Could not find all values for condensator " + condensator.name() + " in properties file.");
			throw e;
		}
	}

	public void setEvenConstant(EnergyData first, EnergyData second) {
		double deltaI = 32768 / (second.time - first.time);
		even[2] = - even[0] * Math.pow(deltaI, even[1]);
		log.debug("even constant set to " + odd[2]);
	}
	
	public void setOddConstant(EnergyData first, EnergyData second) {
		double deltaI = 32768 / (second.time - first.time);
		odd[2] = - odd[0] * Math.pow(deltaI, odd[1]);
		log.debug("odd constant set to " + odd[2]);
	}
	
	public void process(EnergyData data) {
		
		if(previous==null) {
			data.current = 0;
		} else if(data.seqno%2==0) {
			double deltaI = 32768.0 / (data.time - previous.time);
			data.current = even[0] * Math.pow(deltaI, even[1]) + even[2];
			//log.debug("pTime="+previous.time+", nTime="+data.time+", deltaI="+deltaI+ ", a="+even[0]+", b="+even[1]+", c="+even[2]+", current="+data.current);
		} else {
			double deltaI = 32768.0 / (data.time - previous.time);
			data.current = odd[0] * Math.pow(deltaI, odd[1]) + odd[2];
			//log.debug("pTime="+previous.time+", nTime="+data.time+", deltaI="+deltaI+ ", a="+odd[0]+", b="+odd[1]+", c="+odd[2]+", current="+data.current);
		}
		previous = data;
	}
	
	public String getDescription() {
		return "Calibrator";
	}
	
}
